package com.hschinese.pronunciation.iseutil;

import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.hschinese.pronunciation.R;
import com.hschinese.pronunciation.interfaces.IseScoreInterface;
import com.hschinese.pronunciation.interfaces.RecognizeFinishListener;
import com.hschinese.pronunciation.interfaces.VolumeListener;
import com.hschinese.pronunciation.utils.Logger;
import com.hschinese.pronunciation.utils.UIUtils;
import com.iflytek.cloud.EvaluatorListener;
import com.iflytek.cloud.EvaluatorResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechEvaluator;
import com.iflytek.cloud.SpeechEvent;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * 语音评测
 * Created by wo on 2015/10/28.
 * 输出
 */
public class IseUtil {
    private static final String TAG = "IseUtil";
    private Context mContext = null;
    private static IseUtil mInstance = null;
    public static final String ISE_RECORD_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/ise.wav";

    // 评测语种
    private String language;
    // 评测题型
    private String category;
    // 结果等级
    private String result_level;
    // 保存
    private String mLastResult;
    private SpeechEvaluator mIse;
    private VolumeListener mVolumeListener = null;
    private IseScoreInterface mScoreListener = null;
    private RecognizeFinishListener mRecognizeFinishListener = null;
    private int preVolume = 0;

    private IseUtil(Context cxt) {
        mContext = cxt;
        mIse = SpeechEvaluator.createEvaluator(mContext, null);
    }

    public static IseUtil getInstance(Context cxt) {
        synchronized (IseUtil.class) {
            if (mInstance == null) {
                mInstance = new IseUtil(cxt);
            }
            return mInstance;
        }
    }

    public void startRecord(String w) {
        setParams();
        mIse.startEvaluating(w, null, mEvaluatorListener);
    }

    public void stopRecord() {
        mIse.stopEvaluating();
    }

    public void setListener(IseScoreInterface listener) {
        mScoreListener = listener;
    }

    public void setVolumeListener(VolumeListener l) { mVolumeListener = l; }

    public void setRecognizeListener(RecognizeFinishListener listener) { mRecognizeFinishListener = listener; }

    // 评测监听接口
    private EvaluatorListener mEvaluatorListener = new EvaluatorListener() {
        @Override
        public void onResult(EvaluatorResult result, boolean isLast) {
            if (isLast) {
                StringBuilder builder = new StringBuilder();
                builder.append(result.getResultString());
                if(!TextUtils.isEmpty(builder)) {
                    mLastResult = builder.toString();
                    getScore(mLastResult);
                }
            }
        }

        @Override
        public void onError(SpeechError error) {
            if(error != null) {
//                Logger.e("SpeechError code: " + error.getErrorCode() + " -Msg- " + error.getMessage());
                errorToast(error.getErrorCode());
            } else {
                Log.d(TAG, "evaluator over");
            }
            if (mRecognizeFinishListener != null) {
                mRecognizeFinishListener.onRecognizeFinish();
            }
        }

        @Override
        public void onBeginOfSpeech() {
            // 此回调表示：sdk内部录音机已经准备好了，用户可以开始语音输入
            Log.d(TAG, "evaluator begin");
        }

        @Override
        public void onEndOfSpeech() {
            // 此回调表示：检测到了语音的尾端点，已经进入识别过程，不再接受语音输入
            Log.d(TAG, "evaluator stoped");
        }

        @Override
        public void onVolumeChanged(int volume, byte[] data) {
            if (mVolumeListener != null && preVolume != volume) {
                mVolumeListener.updateVolume(volume);
            }
            Log.d(TAG, "返回音频数据：" + data.length);
        }

        @Override
        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
            // 以下代码用于获取与云端的会话id，当业务出错时将会话id提供给技术支持人员，可用于查询会话日志，定位出错原因
            if (SpeechEvent.EVENT_SESSION_ID == eventType) {
                String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
                Log.d(TAG, "session id =" + sid);
                errorToast(eventType);
                if (mRecognizeFinishListener != null) {
                    mRecognizeFinishListener.onRecognizeFinish();
                }
            }
        }

    };

    private float getScore(String s) {
        String ss = "total_score=\"";
        int pos = s.indexOf(ss) + ss.length();
        float score = Float.valueOf(s.substring(pos, pos + 8));
//        Logger.e("xionghy-score-line: " + score);
        if (mScoreListener != null) {
            mScoreListener.scoreResult(score);
        }
        if (mRecognizeFinishListener != null) {
            mRecognizeFinishListener.onRecognizeFinish();
        }
        return score;
    }

//    private void parseXml() {
//        if (mLastResult == null || TextUtils.isEmpty(mLastResult)) {
//            return;
//        }
//        XmlResultParser resultParser = new XmlResultParser();
//        IseResult result = resultParser.parse(mLastResult);
//
//        if (null != result) {
//            Logger.e("Score: " + result.total_score);
//            mScoreListener.scoreResult(result.total_score);
//        } else {
//            Logger.e("结析结果为空");
//        }
//    }

    private void setParams() {
        // 设置评测语言
        language = "zh_cn";
        // 设置需要评测的类型
        category = "read_word";
        // 设置结果等级（中文仅支持complete）
        result_level = "complete";
        // 设置语音前端点:静音超时时间，即用户多长时间不说话则当做超时处理
        String vad_bos = "5000";
        // 设置语音后端点:后端点静音检测时间，即用户停止说话多长时间内即认为不再输入， 自动停止录音
        String vad_eos = "1800";
        // 语音输入超时时间，即用户最多可以连续说多长时间；
        String speech_timeout = "-1";

        mIse.setParameter(SpeechConstant.LANGUAGE, language);
        mIse.setParameter(SpeechConstant.ISE_CATEGORY, category);
        mIse.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");
        mIse.setParameter(SpeechConstant.VAD_BOS, vad_bos);
        mIse.setParameter(SpeechConstant.VAD_EOS, vad_eos);
        mIse.setParameter(SpeechConstant.KEY_SPEECH_TIMEOUT, speech_timeout);
        mIse.setParameter(SpeechConstant.RESULT_LEVEL, result_level);

        // 设置音频保存路径，保存音频格式支持pcm、wav，设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
        // 注：AUDIO_FORMAT参数语记需要更新版本才能生效
        mIse.setParameter(SpeechConstant.AUDIO_FORMAT,"wav");
        mIse.setParameter(SpeechConstant.ISE_AUDIO_PATH, ISE_RECORD_PATH);
    }

    public void destory() {
        if (mIse != null)
            mIse.cancel(false);
    }

    private void errorToast(int err) {
        if (err == 10118) {
            UIUtils.showToast(mContext, mContext.getResources().getString(R.string.err_10118), Toast.LENGTH_SHORT);
        } else if (err == 10200) {
            UIUtils.showToast(mContext, mContext.getResources().getString(R.string.err_10200), Toast.LENGTH_SHORT);
        } else if (err == 10214) {
            UIUtils.showToast(mContext, mContext.getResources().getString(R.string.err_10214), Toast.LENGTH_SHORT);
        } else if (err == 20002) {
            UIUtils.showToast(mContext, mContext.getResources().getString(R.string.err_20002), Toast.LENGTH_SHORT);
        } else if (err == 20003) {
            UIUtils.showToast(mContext, mContext.getResources().getString(R.string.err_20003), Toast.LENGTH_SHORT);
        } else if (err == 20007) {
            UIUtils.showToast(mContext, mContext.getResources().getString(R.string.err_20007), Toast.LENGTH_SHORT);
        } else if (err == 20008) {
            UIUtils.showToast(mContext, mContext.getResources().getString(R.string.err_20008), Toast.LENGTH_SHORT);
        }

    }
}
